package com.leansoft.bigqueue;

import java.io.Closeable;
import java.io.IOException;

/**
 * Append Only Big Array ADT
 *
 * @author bulldog
 */
public interface IBigArray extends Closeable {

    public static final long NOT_FOUND = -1;

    /**
     * Append the data into the head of the array
     * 将数据添加到数组头
     *
     * @param data binary data to append
     * @return appended index
     * @throws IOException if there is any IO error
     */
    long append(byte[] data) throws IOException;


    /**
     * Get the data at specific index
     * 拿到序号上的数据
     *
     * @param index valid data index
     * @return binary data if the index is valid
     * @throws IOException if there is any IO error
     */
    byte[] get(long index) throws IOException;

    /**
     * Get the timestamp of data at specific index,
     * <p>
     * this is the timestamp when the data was appended.
     * 拿到序号上的时间戳，数据被添加的时间
     *
     * @param index valid data index
     * @return timestamp when the data was appended
     * @throws IOException if there is any IO error
     */
    long getTimestamp(long index) throws IOException;

    /**
     * The total number of items has been appended into the array
     * 数组元素的数量
     *
     * @return total number
     */
    long size();


    /**
     * Get the back data file size per page.
     * pageSize，页大小
     *
     * @return size per page
     */
    int getDataPageSize();

    /**
     * The head of the array.
     * 数组头的序号
     * <p>
     * This is the next to append index, the index of the last appended data
     * is [headIndex - 1] if the array is not empty.
     *
     * @return an index
     */
    long getHeadIndex();

    /**
     * The tail of the array.
     * 数组尾的序号
     * <p>
     * The is the index of the first appended data
     *
     * @return an index
     */
    long getTailIndex();

    /**
     * Check if the array is empty or not
     * 是否为空
     *
     * @return true if empty false otherwise
     */
    boolean isEmpty();

    /**
     * Check if the ring space of java long type has all been used up.
     * <p>
     * can always assume false, if true, the world is end:)
     * 数组是不是满了，几乎不能发生
     *
     * @return array full or not
     */
    boolean isFull();

    /**
     * Remove all data in this array, this will empty the array and delete all back page files.
     * 删除数组所有数据
     */
    void removeAll() throws IOException;

    /**
     * Remove all data before specific index, this will advance the array tail to index and
     * delete back page files before index.
     * 删除索引之前的所有数据
     *
     * @param index an index
     * @throws IOException exception thrown if there was any IO error during the removal operation
     */
    void removeBeforeIndex(long index) throws IOException;

    /**
     * Remove all data before specific timestamp, this will advance the array tail and delete back page files
     * accordingly.
     * 删除时间戳之间的所有数据
     *
     * @param timestamp a timestamp
     * @throws IOException exception thrown if there was any IO error during the removal operation
     */
    void removeBefore(long timestamp) throws IOException;

    /**
     * Force to persist newly appended data,
     * <p>
     * normally, you don't need to flush explicitly since:
     * 1.) BigArray will automatically flush a cached page when it is replaced out,
     * 2.) BigArray uses memory mapped file technology internally, and the OS will flush the changes even your process crashes,
     * <p>
     * call this periodically only if you need transactional reliability and you are aware of the cost to performance.
     * 将数组数据刷到磁盘中
     * 一般地，BigArray 在这两种情况下会自己刷磁盘：
     * 1. 当缓存失效，缓存页被替代时，脏页会刷磁盘。
     * 2. BigArray 使用内存映射 mmap，因此当程序崩溃时，操作系统会自动刷磁盘。
     */
    void flush();

    /**
     * Find an index closest to the specific timestamp when the corresponding item was appended
     * 找到当前时间戳最为接近的序号
     *
     * @param timestamp when the corresponding item was appended
     * @return an index
     * @throws IOException exception thrown if there was any IO error during the getClosestIndex operation
     */
    long findClosestIndex(long timestamp) throws IOException;


    /**
     * Get total size of back files(index and data files) of the big array
     *
     * @return total size of back files
     * @throws IOException exception thrown if there was any IO error during the getBackFileSize operation
     */
    long getBackFileSize() throws IOException;

    /**
     * limit the back file size, truncate back file and advance array tail index accordingly,
     * Note, this is a best effort call, exact size limit can't be guaranteed
     *
     * @param sizeLimit the size to limit
     * @throws IOException exception thrown if there was any IO error during the limitBackFileSize operation
     */
    void limitBackFileSize(long sizeLimit) throws IOException;


    /**
     * Get the data item length at specific index
     * 获得序号下数据长度
     * @param index valid data index
     * @return the length of binary data if the index is valid
     * @throws IOException if there is any IO error
     */
    int getItemLength(long index) throws IOException;
}
